<script setup lang="ts">
import { ref } from 'vue'
import * as mars3d from 'mars3d'

type MaybeTilesetLayer = mars3d.layer.TilesetLayer | null

const basePath = ref('D:/work/2025/line')
const tilesZJ12 = ref<MaybeTilesetLayer>(null)
const tilesZJ3 = ref<MaybeTilesetLayer>(null)
const glbLon = ref<number>(119.45)
const glbLat = ref<number>(32.21)
const glbAlt = ref<number>(30)
const glbRel = ref('test/BlockB/BlockB_L17_1.glb')

function toFileUrl(path: string): string {
  // 统一为正斜杠并进行 URI 编码（特别是中文与空格）
  const normalized = path.replace(/\\/g, '/').replace(/^[a-zA-Z]:/, (m) => m.toLowerCase())
  // 保留冒号后的斜杠，例如 d:/ → /d:/
  let p = normalized
  if (/^[a-z]:\//.test(normalized)) {
    p = '/' + normalized
  }
  return encodeURI('file://' + p)
}

function getMap(): mars3d.Map | null {
  // @ts-ignore
  return (window as any).map || null
}

function addTileset(name: string, tilesetJsonPath: string): mars3d.layer.TilesetLayer | null {
  const map = getMap()
  if (!map) return null
  const url = toFileUrl(tilesetJsonPath)
  const layer = new mars3d.layer.TilesetLayer({
    name,
    url,
    maximumScreenSpaceError: 16,
    dynamicScreenSpaceError: true,
    cullWithChildrenBounds: true,
  })
  map.addLayer(layer)
  try { layer.flyTo() } catch {}
  return layer
}

function removeLayer(layer: mars3d.layer.BaseLayer | null) {
  const map = getMap()
  if (!map || !layer) return
  try { map.removeLayer(layer) } catch {}
}

function loadZJ12() {
  if (tilesZJ12.value) return
  const path = `${basePath.value}/20250926镇江/1+2/terra_b3dms/tileset.json`
  tilesZJ12.value = addTileset('镇江 1+2', path)
}

function unloadZJ12() {
  removeLayer(tilesZJ12.value)
  tilesZJ12.value = null
}

function loadZJ3() {
  if (tilesZJ3.value) return
  const path = `${basePath.value}/20250926镇江/3/terra_b3dms/tileset.json`
  tilesZJ3.value = addTileset('镇江 3', path)
}

function unloadZJ3() {
  removeLayer(tilesZJ3.value)
  tilesZJ3.value = null
}

// 简单的 GLB 加载（需要经纬度定位）
function loadGLB() {
  const map = getMap()
  if (!map) return
  // @ts-ignore 全局共享的图层（若不存在则创建）
  let layer: mars3d.layer.GraphicLayer = (window as any).GLBLayer
  if (!layer) {
    layer = new mars3d.layer.GraphicLayer({ name: 'GLBLayer' })
    map.addLayer(layer)
    // @ts-ignore
    ;(window as any).GLBLayer = layer
  }
  const url = toFileUrl(`${basePath.value}/${glbRel.value}`)
  const model = new mars3d.graphic.ModelEntity({
    position: [glbLon.value, glbLat.value, glbAlt.value],
    style: {
      url,
      scale: 1,
      minimumPixelSize: 64,
      distanceDisplayCondition: true,
      shadows: true,
    },
  })
  model.addTo(layer)
  try { layer.flyTo() } catch {}
}
</script>

<template>
  <div class="dji3d-panel">
    <div class="row">
      <label>根目录</label>
      <input v-model="basePath" class="ipt" placeholder="例如 D:/work/2025/line" />
    </div>
    <div class="row group">
      <div class="col">
        <div class="title">镇江 1+2</div>
        <button class="btn" @click="loadZJ12" :disabled="!!tilesZJ12">加载</button>
        <button class="btn danger" @click="unloadZJ12" :disabled="!tilesZJ12">移除</button>
      </div>
      <div class="col">
        <div class="title">镇江 3</div>
        <button class="btn" @click="loadZJ3" :disabled="!!tilesZJ3">加载</button>
        <button class="btn danger" @click="unloadZJ3" :disabled="!tilesZJ3">移除</button>
      </div>
    </div>
    <div class="row">
      <div class="title">测试 GLB</div>
      <input v-model.number="glbLon" class="ipt small" type="number" step="0.000001" placeholder="经度" />
      <input v-model.number="glbLat" class="ipt small" type="number" step="0.000001" placeholder="纬度" />
      <input v-model.number="glbAlt" class="ipt small" type="number" step="1" placeholder="高程" />
    </div>
    <div class="row">
      <input v-model="glbRel" class="ipt" placeholder="相对根目录的GLB路径，如 test/BlockB/BlockB_L17_1.glb" />
      <button class="btn" @click="loadGLB">加载 GLB</button>
    </div>
  </div>
</template>

<style scoped>
.dji3d-panel {
  position: absolute;
  z-index: 21;
  right: 10px;
  top: 60px;
  width: 420px;
  background: rgba(20,20,20,.65);
  backdrop-filter: saturate(150%) blur(4px);
  padding: 12px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,.08);
  box-shadow: 0 8px 16px rgba(0,0,0,.25);
  color: #eaeaea;
}
.row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.group { justify-content: space-between; }
.col { display: flex; align-items: center; gap: 8px; }
.title { font-weight: 600; margin-right: 6px; }
label { opacity: .85; min-width: 52px; }
.ipt { flex: 1; min-width: 0; height: 30px; padding: 4px 8px; border-radius: 6px; border: 1px solid rgba(255,255,255,.18); background: rgba(255,255,255,.06); color: #eaeaea; }
.ipt.small { width: 110px; flex: unset; }
.btn { padding: 6px 10px; line-height: 1; color: #eaeaea; background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.08); border-radius: 6px; cursor: pointer; transition: all .15s ease; }
.btn:hover { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.18); }
.btn.danger { color: #fff; background: rgba(217,83,79,.15); border-color: rgba(217,83,79,.35); }
.btn.danger:hover { background: rgba(217,83,79,.25); border-color: rgba(217,83,79,.55); }
</style>


